/******************** (C) COPYRIGHT 2017 ANO Tech ********************************
 * 作者    ：匿名科创
 * 官网    ：www.anotc.com
 * 淘宝    ：anotc.taobao.com
 * 技术Q群 ：190169595
 * 描述    ：任务调度
**********************************************************************************/
#include "Ano_Scheduler.h"
#include "usbd_hid.h"
#include "ws2812.h"
#include "defines.h"

Flag_struct flag;
u32 test_dT_1000hz[3],test_rT[6];

static void Loop_1000Hz(void)	//1ms执行一次
{

}

static void Loop_500Hz(void)	//2ms执行一次
{

}

static void Loop_200Hz(void)	//5ms执行一次
{

}

static void Loop_100Hz(void)	//10ms执行一次
{

				
}


	RB_Buff RB1;
	RB_Buff RB2;
	RB_Buff RB3;
	RB_Buff RB4;
	RB_Buff RB5;
	RB_Buff RB6;

#define LEDMODE_NUM 2
static void Loop_50Hz(void)	//20ms执行一次
{
//	uint8_t R,G,B=0;
//	R=
//	G=;
//	B=);
//	
static int i=0;
	switch(flag.LED_Mode){
		case 0:
			WS2812_Set_ALL(PM_Func(R),PM_Func(G),PM_Func(B));
		break;
		
		case 1:
			WS2812_Set(i,PM_Func(R),PM_Func(G),PM_Func(B));
			i++;
			if(i>15){i=0;}
			break;
			
		case 2:
			WS2812_Set_ALL(RainbolFunc(&RB1,0),RainbolFunc(&RB2,200),RainbolFunc(&RB3,400));
		break;
}
}


static void Loop_20Hz(void)	//50ms执行一次
{

}

static void Loop_2Hz(void)	//500ms执行一次
{

}
/*buffer[0]特殊按键
|--bit0: Left Control是否按下，按下为1

|--bit1: Left Shift 是否按下，按下为1

|--bit2: Left Alt 是否按下，按下为1

|--bit3: Left GUI 是否按下，按下为1

|--bit4: Right Control是否按下，按下为1

|--bit5: Right Shift 是否按下，按下为1

|--bit6: Right Alt 是否按下，按下为1

|--bit7: Right GUI 是否按下，按下为1
大端在前，如0x80为GUI，0x01为左CTRL

buffer[1]默认为0

buffer[2]到[6]为普通按键，以0x04 a为开头abcd顺序
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
uint8_t buffer[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t buffer_0[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t buffer_last=0;
static void Keyboard_Task(void)
{
	static int i=0;
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==1)
			{
				buffer[0]=0x01;
				buffer[2] = 0x06;
			if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)==1)
			{
				flag.LED_Mode+=1;
				if(flag.LED_Mode>=LEDMODE_NUM){flag.LED_Mode=0;}
			}
			}
		else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)==1)
			{
				buffer[0]=0x01;
				buffer[2] = 0x19;
			}
		else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1)
			{
				buffer[0]=0x01;
				buffer[2] = 0x16;
			}
//		else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_15)==1)
//			{
//				buffer[0]=0x00;
//				buffer[2] = 0x2A;
//			}
		else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7)==1)
			{
				buffer[0]=0x00;
				buffer[2] = 0x28;
			}



			
		if(buffer[2]!=0){
			if(buffer[2]==buffer_last){i++;}//单个按键延时，切换按键需要立即响应
			if(i==4 || buffer[2]!=buffer_last){
				i=0;
				USBD_HID_SendReport(&hUsbDeviceFS, buffer, 8); //send
				HAL_Delay(10); //delay
				USBD_HID_SendReport(&hUsbDeviceFS, buffer_0, 8);
				buffer[2]=0;
				}

		}
		buffer_last=buffer[2];
}
//系统任务配置，创建不同执行频率的“线程”
static sched_task_t sched_tasks[] = 
{
	{Loop_1000Hz,1000,  0, 0},
	{Loop_500Hz , 500,  0, 0},
	{Loop_200Hz , 200,  0, 0},
	{Loop_100Hz , 100,  0, 0},
	{Loop_50Hz  ,  50,  0, 0},
	{Loop_20Hz  ,  20,  0, 0},
	{Keyboard_Task ,10,  0, 0},
	{Loop_2Hz   ,   2,  0, 0},
};
//根据数组长度，判断线程数量
#define TASK_NUM (sizeof(sched_tasks)/sizeof(sched_task_t))

void Scheduler_Setup(void)
{
	uint8_t index = 0;
	//初始化任务表
	for(index=0;index < TASK_NUM;index++)
	{
		//计算每个任务的延时周期数
		sched_tasks[index].interval_ticks = TICK_PER_SECOND/sched_tasks[index].rate_hz;
		//最短周期为1，也就是1ms
		if(sched_tasks[index].interval_ticks < 1)
		{
			sched_tasks[index].interval_ticks = 1;
		}
	}
}
//这个函数放到main函数的while(1)中，不停判断是否有线程应该执行
void Scheduler_Run(void)
{
	uint8_t index = 0;
	//循环判断所有线程，是否应该执行

	
	for(index=0;index < TASK_NUM;index++)
	{
		//获取系统当前时间，单位MS
		uint32_t tnow = HAL_GetTick();
		//进行判断，如果当前时间减去上一次执行的时间，大于等于该线程的执行周期，则执行线程
		if(tnow - sched_tasks[index].last_run >= sched_tasks[index].interval_ticks)
		{
			
			//更新线程的执行时间，用于下一次判断
			sched_tasks[index].last_run = tnow;
			//执行线程函数，使用的是函数指针
			sched_tasks[index].task_func();

		}	 
	}
	

}



/******************* (C) COPYRIGHT 2014 ANO TECH *****END OF FILE************/
	

